package com.ssy.lingxi.marketing.serviceimpl.base.activity;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.constant.marketing.ActivityTypeEnum;
import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.constant.marketing.PlatformCouponTypeEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.marketing.api.model.constant.MkRedisKeyConstants;
import com.ssy.lingxi.marketing.entity.activity.MerchantActivityDO;
import com.ssy.lingxi.marketing.entity.activity.PlatformActivityDO;
import com.ssy.lingxi.marketing.entity.coupon.CouponGoodsDO;
import com.ssy.lingxi.marketing.entity.coupon.MerchantCouponDO;
import com.ssy.lingxi.marketing.entity.coupon.PlatformCouponDO;
import com.ssy.lingxi.marketing.model.bo.*;
import com.ssy.lingxi.marketing.model.constant.*;
import com.ssy.lingxi.marketing.model.dto.ActivityCommonInfoDTO;
import com.ssy.lingxi.marketing.model.vo.coupon.response.ActivityPageCouponDetailResponse;
import com.ssy.lingxi.marketing.model.vo.coupon.response.ActivityPrizeCouponResponse;
import com.ssy.lingxi.marketing.model.vo.coupon.response.SuitableProductVO;
import com.ssy.lingxi.marketing.repository.*;
import com.ssy.lingxi.marketing.service.feign.IPlatformManageFeignService;
import com.ssy.lingxi.marketing.utils.ValidatorUtil;
import com.ssy.lingxi.platform.manage.api.model.vo.shop.ShopVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 基础营销活动服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/8/16
 */
@Slf4j
@Service
public class BaseActivityService {

    @Resource
    private MerchantCouponRepository merchantCouponRepository;
    @Resource
    private PlatformCouponRepository platformCouponRepository;
    @Resource
    private CouponGoodsRepository couponGoodsRepository;
    @Resource
    private IPlatformManageFeignService platformManageFeignService;
    @Resource
    private PlatformActivityRepository platformActivityRepository;
    @Resource
    private MerchantActivityRepository merchantActivityRepository;
    @Autowired
    private IRedisStringUtils redisStringUtils;
    /**
     * 获取活动定义数据
     * @param belongTypeEnum 所属类型
     * @param activityType 活动类型
     * @param activityDefined 活动定义
     * @return 返回结果
     */
    public JSONObject getActivityDefine(BelongTypeEnum belongTypeEnum, Integer activityType, ActivityDefinedBO activityDefined) {
        JSONObject jsonObject = JSONUtil.parseObj(activityDefined);
        // 抽奖
        if (ActivityTypeEnum.LOTTERY.getCode().equals(activityType)) {
            LotteryBO lotteryBO = (LotteryBO) activityDefined;
            List<PrizeBO> prizeBOList = lotteryBO.getPrizeList();

            List<Long> couponIdList = prizeBOList.stream()
                    .filter(prizeBO -> PrizeTypeEnum.PRODUCT.getCode().equals(prizeBO.getType()) || PrizeTypeEnum.COUPON.getCode().equals(prizeBO.getType()))
                    .map(PrizeBO::getPrize)
                    .filter(prize -> Pattern.matches("^[1-9]*$", prize))
                    .map(Long::valueOf).collect(Collectors.toList());

            // 如果有奖品
            if (!CollectionUtils.isEmpty(couponIdList)) {
                if (BelongTypeEnum.PLATFORM.equals(belongTypeEnum)) {
                    Map<Long, PlatformCouponDO> platformCouponDOMap = platformCouponRepository.findAllById(couponIdList).stream().collect(Collectors.toMap(PlatformCouponDO::getId, e -> e, (e1, e2) -> e2));
                    JSONArray prizeList = jsonObject.getJSONArray("prizeList");
                    for (Object o : prizeList) {
                        JSONObject jo = (JSONObject) o;
                        Integer prizeType = jo.getInt("type");
                        if (PrizeTypeEnum.PRODUCT.getCode().equals(prizeType)) {
                            PlatformCouponDO couponDO = platformCouponDOMap.getOrDefault(jo.getLong("prize"), new PlatformCouponDO());
                            ActivityPrizeCouponResponse couponDetail = new ActivityPrizeCouponResponse();
                            couponDetail.setId(couponDO.getId());
                            couponDetail.setName(couponDO.getName());
                            couponDetail.setType(couponDO.getType());
                            couponDetail.setTypeName(PlatformCouponTypeEnum.getCodeMessage(couponDO.getType()));
                            couponDetail.setDenomination(couponDO.getDenomination());
                            couponDetail.setGetWay(couponDO.getGetWay());
                            couponDetail.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(couponDO.getGetWay()));
                            couponDetail.setUseConditionMoney(couponDO.getUseConditionMoney());
                            couponDetail.setEffectiveType(couponDO.getEffectiveType());
                            couponDetail.setEffectiveTypeName(PlatformCouponEffectiveTypeEnum.getCodeMessage(couponDO.getEffectiveType()));
                            couponDetail.setEffectiveTimeStart(couponDO.getEffectiveTimeStart());
                            couponDetail.setEffectiveTimeEnd(couponDO.getEffectiveTimeEnd());
                            couponDetail.setInvalidDay(couponDO.getInvalidDay());
                            couponDetail.setCreateTime(couponDO.getCreateTime());
                            // 查询0元抵扣商品
                            CouponGoodsDO couponGoodsDO = couponGoodsRepository.findFirstByBelongTypeAndCouponId(belongTypeEnum.getCode(), couponDO.getId());
                            if (Objects.nonNull(couponGoodsDO)) {
                                SuitableProductVO suitableProductVO = new SuitableProductVO();
                                suitableProductVO.setProductId(couponGoodsDO.getProductId());
                                suitableProductVO.setSkuId(couponGoodsDO.getSkuId());
                                suitableProductVO.setProductName(couponGoodsDO.getProductName());
                                suitableProductVO.setType(couponGoodsDO.getType());
                                suitableProductVO.setCategory(couponGoodsDO.getCategory());
                                suitableProductVO.setBrand(couponGoodsDO.getBrand());
                                suitableProductVO.setUnit(couponGoodsDO.getUnit());
                                suitableProductVO.setPrice(couponGoodsDO.getPrice());
                                suitableProductVO.setProductImgUrl(couponGoodsDO.getProductImgUrl());
                                couponDetail.setSuitableProduct(suitableProductVO);
                            }

                            jo.set("coupon", couponDetail);
                        } else if (PrizeTypeEnum.COUPON.getCode().equals(prizeType)) {
                            PlatformCouponDO platformCouponDO = platformCouponDOMap.getOrDefault(jo.getLong("prize"), new PlatformCouponDO());
                            ActivityPageCouponDetailResponse couponDetail = new ActivityPageCouponDetailResponse();
                            couponDetail.setId(platformCouponDO.getId());
                            couponDetail.setName(platformCouponDO.getName());
                            couponDetail.setType(platformCouponDO.getType());
                            couponDetail.setTypeName(PlatformCouponTypeEnum.getCodeMessage(platformCouponDO.getType()));
                            couponDetail.setReleaseTimeStart(platformCouponDO.getReleaseTimeStart());
                            couponDetail.setReleaseTimeEnd(platformCouponDO.getReleaseTimeEnd());
                            couponDetail.setDenomination(platformCouponDO.getDenomination());
                            couponDetail.setGetWay(platformCouponDO.getGetWay());
                            couponDetail.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(platformCouponDO.getGetWay()));
                            couponDetail.setUseConditionMoney(platformCouponDO.getUseConditionMoney());
                            couponDetail.setCreateTime(platformCouponDO.getCreateTime());
                            couponDetail.setBelongType(belongTypeEnum.getCode());
                            couponDetail.setBelongName(belongTypeEnum.getMessage());
                            jo.set("coupon", couponDetail);
                        }
                    }
                } else if (BelongTypeEnum.MERCHANT.equals(belongTypeEnum)) {
                    Map<Long, MerchantCouponDO> merchantCouponDOMap = merchantCouponRepository.findAllById(couponIdList).stream().collect(Collectors.toMap(MerchantCouponDO::getId, e -> e, (e1, e2) -> e2));
                    JSONArray prizeList = jsonObject.getJSONArray("prizeList");
                    for (Object o : prizeList) {
                        JSONObject jo = (JSONObject) o;
                        Integer prizeType = jo.getInt("type");
                        if (PrizeTypeEnum.PRODUCT.getCode().equals(prizeType)) {
                            MerchantCouponDO couponDO = merchantCouponDOMap.getOrDefault(jo.getLong("prize"), new MerchantCouponDO());
                            ActivityPrizeCouponResponse couponDetail = new ActivityPrizeCouponResponse();
                            couponDetail.setId(couponDO.getId());
                            couponDetail.setName(couponDO.getName());
                            couponDetail.setType(couponDO.getType());
                            couponDetail.setTypeName(PlatformCouponTypeEnum.getCodeMessage(couponDO.getType()));
                            couponDetail.setDenomination(couponDO.getDenomination());
                            couponDetail.setGetWay(couponDO.getGetWay());
                            couponDetail.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(couponDO.getGetWay()));
                            couponDetail.setUseConditionMoney(couponDO.getUseConditionMoney());
                            couponDetail.setEffectiveType(couponDO.getEffectiveType());
                            couponDetail.setEffectiveTypeName(PlatformCouponEffectiveTypeEnum.getCodeMessage(couponDO.getEffectiveType()));
                            couponDetail.setEffectiveTimeStart(couponDO.getEffectiveTimeStart());
                            couponDetail.setEffectiveTimeEnd(couponDO.getEffectiveTimeEnd());
                            couponDetail.setInvalidDay(couponDO.getInvalidDay());
                            couponDetail.setCreateTime(couponDO.getCreateTime());
                            // 查询0元抵扣商品
                            CouponGoodsDO couponGoodsDO = couponGoodsRepository.findFirstByBelongTypeAndCouponId(belongTypeEnum.getCode(), couponDO.getId());
                            if (Objects.nonNull(couponGoodsDO)) {
                                SuitableProductVO suitableProductVO = new SuitableProductVO();
                                suitableProductVO.setProductId(couponGoodsDO.getProductId());
                                suitableProductVO.setSkuId(couponGoodsDO.getSkuId());
                                suitableProductVO.setProductName(couponGoodsDO.getProductName());
                                suitableProductVO.setType(couponGoodsDO.getType());
                                suitableProductVO.setCategory(couponGoodsDO.getCategory());
                                suitableProductVO.setBrand(couponGoodsDO.getBrand());
                                suitableProductVO.setUnit(couponGoodsDO.getUnit());
                                suitableProductVO.setPrice(couponGoodsDO.getPrice());
                                suitableProductVO.setProductImgUrl(couponGoodsDO.getProductImgUrl());
                                couponDetail.setSuitableProduct(suitableProductVO);
                            }

                            jo.set("coupon", couponDetail);
                        } else if (PrizeTypeEnum.COUPON.getCode().equals(prizeType)) {
                            MerchantCouponDO couponDO = merchantCouponDOMap.getOrDefault(jo.getLong("prize"), new MerchantCouponDO());
                            ActivityPageCouponDetailResponse couponDetail = new ActivityPageCouponDetailResponse();
                            couponDetail.setId(couponDO.getId());
                            couponDetail.setName(couponDO.getName());
                            couponDetail.setType(couponDO.getType());
                            couponDetail.setTypeName(PlatformCouponTypeEnum.getCodeMessage(couponDO.getType()));
                            couponDetail.setReleaseTimeStart(couponDO.getReleaseTimeStart());
                            couponDetail.setReleaseTimeEnd(couponDO.getReleaseTimeEnd());
                            couponDetail.setDenomination(couponDO.getDenomination());
                            couponDetail.setGetWay(couponDO.getGetWay());
                            couponDetail.setGetWayName(PlatformCouponGetWayEnum.getCodeMessage(couponDO.getGetWay()));
                            couponDetail.setUseConditionMoney(couponDO.getUseConditionMoney());
                            couponDetail.setCreateTime(couponDO.getCreateTime());
                            couponDetail.setBelongType(belongTypeEnum.getCode());
                            couponDetail.setBelongName(belongTypeEnum.getMessage());
                            jo.set("coupon", couponDetail);
                        }
                    }
                }
            }
        }
        return jsonObject;
    }

    /**
     * 根据活动类型解析活动json
     *
     * @param activityType 活动类型
     * @param jsonObject   活动json
     * @return 返回结果
     */
    protected ActivityDefinedBO parseActivityDefinedBO(Integer activityType, JSONObject jsonObject) {
        ActivityDefinedBO activityDefinedBO = null;
        switch (activityType) {
            case 1:
                activityDefinedBO = JSONUtil.toBean(jsonObject, SpecialOfferBO.class);
                break;
            case 2:
                activityDefinedBO = JSONUtil.toBean(jsonObject, PlummetBO.class);
                break;
            case 3:
                activityDefinedBO = JSONUtil.toBean(jsonObject, DiscountBO.class);
                break;
            case 4:
                activityDefinedBO = JSONUtil.toBean(jsonObject, FullQuantityBO.class);
                break;
            case 5:
                activityDefinedBO = JSONUtil.toBean(jsonObject, FullMoneyBO.class);
                break;
            case 6:
                activityDefinedBO = JSONUtil.toBean(jsonObject, GiveBO.class);
                break;
            case 7:
                activityDefinedBO = JSONUtil.toBean(jsonObject, MorePieceBO.class);
                break;
            case 8:
                activityDefinedBO = JSONUtil.toBean(jsonObject, CombinationBO.class);
                break;
            case 9:
                activityDefinedBO = JSONUtil.toBean(jsonObject, GroupPurchaseBO.class);
                break;
            case 10:
                activityDefinedBO = JSONUtil.toBean(jsonObject, LotteryBO.class);
                break;
            case 11:
                activityDefinedBO = JSONUtil.toBean(jsonObject, BargainBO.class);
                break;
            case 12:
                activityDefinedBO = JSONUtil.toBean(jsonObject, SecKillBO.class);
                break;
            case 13:
                activityDefinedBO = JSONUtil.toBean(jsonObject, SwapBO.class);
                break;
            case 14:
                activityDefinedBO = JSONUtil.toBean(jsonObject, PreSaleBO.class);
                break;
            case 15:
                activityDefinedBO = JSONUtil.toBean(jsonObject, SetMealBO.class);
                break;
            case 16:
                activityDefinedBO = JSONUtil.toBean(jsonObject, AttemptBO.class);
                break;
        }
        if (activityDefinedBO != null) {
            activityDefinedBO.setActivityType(activityType);
        }
        return activityDefinedBO;
    }

    /**
     * 判断活动时间
     * @param currentTimeMillis 当前时间
     * @param startTime 活动开始时间
     * @param endTime 活动结束时间
     * @return 返回结果
     */
    protected Wrapper<Void> checkActivityTime(Long currentTimeMillis, Long startTime, Long endTime) {
        // 判断活动时间
        if (Objects.isNull(startTime) || Objects.isNull(endTime)) {
            return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_END_TIME_ERROR);
        }
        // 活动开始时间要大于当前时间
        if (currentTimeMillis >= startTime) {
            return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_START_TIME_ERROR);
        }
        // 活动结束时间要大于当前时间
        if (currentTimeMillis >= endTime) {
            return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_END_TIME_ERROR);
        }
        // 活动结束时间要大于活动开始时间
        if (startTime >= endTime) {
            return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_END_TIME_GE_ACTIVITY_START_TIME);
        }

        return Wrapper.success();
    }

    /**
     * 校验各种活动类型对应的参数
     *
     * @param activityType      活动类型
     * @param activityDefinedBO 活动json
     */
    protected Wrapper<Void> checkActivityDefine(Integer activityType, JSONObject activityDefinedBO) {
        // 校验对应活动类型的参数
        if (ActivityTypeEnum.SPECIAL_OFFER.getCode().equals(activityType)) {
            // 特价促销
            SpecialOfferBO specialOfferBO = JSONUtil.toBean(activityDefinedBO, SpecialOfferBO.class);
            ValidatorUtil.validate(specialOfferBO);
        } else if (ActivityTypeEnum.PLUMMET.getCode().equals(activityType)) {
            // 直降促销
            PlummetBO plummetBO = JSONUtil.toBean(activityDefinedBO, PlummetBO.class);
            ValidatorUtil.validate(plummetBO);
        } else if (ActivityTypeEnum.DISCOUNT.getCode().equals(activityType)) {
            // 折扣促销
            DiscountBO discountBO = JSONUtil.toBean(activityDefinedBO, DiscountBO.class);
            ValidatorUtil.validate(discountBO);
        } else if (ActivityTypeEnum.FULL_QUANTITY.getCode().equals(activityType)) {
            // 满量促销
            FullQuantityBO fullQuantityBO = JSONUtil.toBean(activityDefinedBO, FullQuantityBO.class);
            ValidatorUtil.validate(fullQuantityBO);

            // 阶梯校验
            List<FullQuantityBO.LadderBO> ladderList = fullQuantityBO.getLadderList();
            if (CollectionUtils.isEmpty(ladderList)) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LADDER_NOT_EMPTY);
            }
            if (!ladderList.stream().map(FullQuantityBO.LadderBO::getKey).allMatch(new HashSet<>()::add)) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LADDER_NO_REPEAT);
            }
        } else if (ActivityTypeEnum.FULL_MONEY.getCode().equals(activityType)) {
            // 满额促销
            FullMoneyBO fullMoneyBO = JSONUtil.toBean(activityDefinedBO, FullMoneyBO.class);
            ValidatorUtil.validate(fullMoneyBO);

            // 阶梯校验
            List<FullMoneyBO.LadderBO> ladderList = fullMoneyBO.getLadderList();
            if (CollectionUtils.isEmpty(ladderList)) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LADDER_NOT_EMPTY);
            }
            if (!ladderList.stream().map(FullMoneyBO.LadderBO::getKey).allMatch(new HashSet<>()::add)) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LADDER_NO_REPEAT);
            }
        } else if (ActivityTypeEnum.GIVE.getCode().equals(activityType)) {
            // 赠送促销
            GiveBO giveBO = JSONUtil.toBean(activityDefinedBO, GiveBO.class);
            ValidatorUtil.validate(giveBO);

        } else if (ActivityTypeEnum.MORE_PIECE.getCode().equals(activityType)) {
            // 多件促销
            MorePieceBO morePieceBO = JSONUtil.toBean(activityDefinedBO, MorePieceBO.class);
            ValidatorUtil.validate(morePieceBO);

            // 阶梯校验
            List<MorePieceBO.LadderBO> ladderList = morePieceBO.getLadderList();
            if (CollectionUtils.isEmpty(ladderList)) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LADDER_NOT_EMPTY);
            }
            if (!ladderList.stream().map(MorePieceBO.LadderBO::getNum).allMatch(new HashSet<>()::add)) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LADDER_NO_REPEAT);
            }
            if (ladderList.stream().map(MorePieceBO.LadderBO::getDiscount).anyMatch(o->o.compareTo(BigDecimal.ONE)<0)) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LADDER_NUM_MIN_ERROR);
            }
        } else if (ActivityTypeEnum.COMBINATION.getCode().equals(activityType)) {
            // 组合促销
            CombinationBO combinationBO = JSONUtil.toBean(activityDefinedBO, CombinationBO.class);
            ValidatorUtil.validate(combinationBO);
        } else if (ActivityTypeEnum.GROUP_PURCHASE.getCode().equals(activityType)) {
            // 拼团
            GroupPurchaseBO groupPurchaseBO = JSONUtil.toBean(activityDefinedBO, GroupPurchaseBO.class);
            ValidatorUtil.validate(groupPurchaseBO);

                if (Objects.isNull(groupPurchaseBO.getAssembleTime()) || 0 >= groupPurchaseBO.getAssembleTime()) {
                    return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_ASSEMBLE_POSITIVE);
                }
                if(Objects.isNull(groupPurchaseBO.getAssembleNum())||groupPurchaseBO.getAssembleNum()<2){
                    return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_ASSEMBLE_NUM_ERROR);
                }
        } else if (ActivityTypeEnum.LOTTERY.getCode().equals(activityType)) {
            // 抽奖
            LotteryBO lotteryBO = JSONUtil.toBean(activityDefinedBO, LotteryBO.class);
            ValidatorUtil.validate(lotteryBO);

            if (LotteryTypeEnum.ORDER.getCode().equals(lotteryBO.getLotteryType())) {
                if (Objects.isNull(lotteryBO.getOrderPrice()) || BigDecimal.ZERO.compareTo(lotteryBO.getOrderPrice()) >= 0) {
                    return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LOTTERY_ORDER_POSITIVE);
                }
            } else if (LotteryTypeEnum.INTEGRAL.getCode().equals(lotteryBO.getLotteryType())) {
                if (Objects.isNull(lotteryBO.getIntegral()) || 0 >= lotteryBO.getIntegral()) {
                    return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LOTTERY_INTEGRAL_POSITIVE);
                }
            } else if (LotteryTypeEnum.BEHAVIOR.getCode().equals(lotteryBO.getLotteryType())) {
                if (Objects.isNull(lotteryBO.getBehavior())) {
                    return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_LOTTERY_INTEGRAL_POSITIVE_NOT_NULL);
                }
            } else if (LotteryTypeEnum.ACTIVITY.getCode().equals(lotteryBO.getLotteryType())) {
                // ignore
            }

        } else if (ActivityTypeEnum.BARGAIN.getCode().equals(activityType)) {
            // 砍价
            BargainBO bargainBO = JSONUtil.toBean(activityDefinedBO, BargainBO.class);
            ValidatorUtil.validate(bargainBO);
            if (BargainTypeEnum.RANDOM.getCode().equals(bargainBO.getType())) {
                if (Objects.isNull(bargainBO.getRandomStartPrice()) || Objects.isNull(bargainBO.getRandomEndPrice())) {
                    return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_BARGAIN_RANDOM_PRICE_NOT_NULL);
                }

                if (BigDecimal.ZERO.compareTo(bargainBO.getRandomStartPrice()) >= 0
                        || bargainBO.getRandomStartPrice().compareTo(bargainBO.getRandomEndPrice()) >= 0) {
                    return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_BARGAIN_RANDOM_PRICE_POSITIVE);
                }

            } else if (BargainTypeEnum.RESTRICT.getCode().equals(bargainBO.getType())) {
                if (Objects.isNull(bargainBO.getRestrictPrice()) || BigDecimal.ZERO.compareTo(bargainBO.getRestrictPrice()) >= 0) {
                    return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_BARGAIN_RESTRICT_PRICE_POSITIVE);
                }
            }
        } else if (ActivityTypeEnum.SEC_KILL.getCode().equals(activityType)) {
            // 秒杀
            SecKillBO secKillBO = JSONUtil.toBean(activityDefinedBO, SecKillBO.class);
            ValidatorUtil.validate(secKillBO);

            if (secKillBO.getStartTime() >= secKillBO.getEndTime()) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_SEC_KILL_TIME_COMPARE);
            }
        } else if (ActivityTypeEnum.SWAP.getCode().equals(activityType)) {
            // 换购
            SwapBO swapBO = JSONUtil.toBean(activityDefinedBO, SwapBO.class);
            ValidatorUtil.validate(swapBO);
        } else if (ActivityTypeEnum.PRE_SALE.getCode().equals(activityType)) {
            // 预售
            PreSaleBO preSaleBO = JSONUtil.toBean(activityDefinedBO, PreSaleBO.class);
            ValidatorUtil.validate(preSaleBO);

            if (preSaleBO.getDepositPayStartTime() >= preSaleBO.getDepositPayEndTime()) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_PRE_SALE_DEPOSIT_TIME_COMPARE);
            }

            if (preSaleBO.getBalancePaymentPayStartTime() >= preSaleBO.getBalancePaymentPayEndTime()) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_PRE_SALE_BALANCE_TIME_COMPARE);
            }

            if (preSaleBO.getBalancePaymentPayEndTime() >= preSaleBO.getDeliverTime()) {
                return Wrapper.fail(ResponseCode.MARKETING_ACTIVITY_PRE_DELIVER_TIME_COMPARE);
            }
        } else if (ActivityTypeEnum.SET_MEAL.getCode().equals(activityType)) {
            // 套餐
            SetMealBO setMealBO = JSONUtil.toBean(activityDefinedBO, SetMealBO.class);
            ValidatorUtil.validate(setMealBO);
        } else if (ActivityTypeEnum.ATTEMPT.getCode().equals(activityType)) {
            // 试用
            AttemptBO attemptBO = JSONUtil.toBean(activityDefinedBO, AttemptBO.class);
            ValidatorUtil.validate(attemptBO);
        }

        // 校验叠加活动是否超出指定范围
        JSONArray allowActivity = activityDefinedBO.getJSONArray("allowActivity");
        if (allowActivity != null) {
            List<Integer> items = allowActivity.toList(Integer.class);
            if (!ActivityTypeEnum.isValidSuperpositionItem(activityType, items)) {
                return Wrapper.fail(ResponseCode.MARKETING_PLATFORM_ACTIVITY_SUPPERPOSITION_TYPE_NOT_ALLOW);
            }
        }

        return Wrapper.success();
    }

    /**
     * 判断是否属于当前会员
     *
     * @param loginUser 登录用户信息
     * @param memberId  记录的memberId
     * @param roleId    记录的roleId
     * @return true false
     */
    protected boolean isBelongCurrentMember(UserLoginCacheDTO loginUser, Long memberId, Long roleId) {
        return loginUser.getMemberId().equals(memberId) && loginUser.getMemberRoleId().equals(roleId);
    }

    /**
     * 获取minType
     *
     * @param activityType 活动类型
     * @param jsonObject   活动json
     * @return 返回结果
     */
    protected Integer getMinType(Integer activityType, JSONObject jsonObject) {
        if (activityType.equals(ActivityTypeEnum.FULL_QUANTITY.getCode())) {
            return jsonObject.getInt("type");
        } else if (activityType.equals(ActivityTypeEnum.FULL_MONEY.getCode())) {
            return jsonObject.getInt("type");
        } else if (activityType.equals(ActivityTypeEnum.GIVE.getCode())) {
            return jsonObject.getInt("giftType");
        } else if (activityType.equals(ActivityTypeEnum.SWAP.getCode())) {
            return jsonObject.getInt("swapType");
        } else {
            return null;
        }
    }

    /**
     * 获取allowCoupon
     */
    protected Integer getAllowCoupon(Integer activityType, JSONObject jsonObject) {
        Boolean value = null;
        if (activityType.equals(ActivityTypeEnum.SPECIAL_OFFER.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.PLUMMET.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.DISCOUNT.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.FULL_QUANTITY.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.FULL_MONEY.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.GIVE.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.MORE_PIECE.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.COMBINATION.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.SEC_KILL.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.SWAP.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        } else if (activityType.equals(ActivityTypeEnum.SET_MEAL.getCode())) {
            value =  jsonObject.getBool("allowCoupon");
        }

        return Optional.ofNullable(value).map(v -> v ? CommonBooleanEnum.YES.getCode() : CommonBooleanEnum.NO.getCode()).orElse(null);
    }

    // 查询商城数据
    public List<ShopVO> getShopVOListByIds(List<Long> shopIds){
        Wrapper<List<ShopVO>> shopWrapper = platformManageFeignService.shopByIdList(shopIds);
            if (ResponseCode.SUCCESS.getCode() != shopWrapper.getCode()) {
            return null;
        }
        return shopWrapper.getData();
    }

    private ActivityCommonInfoDTO buildActivityCommonInfoDTO(Long id,Integer activityType,Long startTime,Long endTime,String activityName,Long createTime,Boolean status){
        ActivityCommonInfoDTO dto=new ActivityCommonInfoDTO();
        dto.setId(id);
        dto.setActivityType(activityType);
        dto.setStartTime(startTime);
        dto.setEndTime(endTime);
        dto.setActivityName(activityName);
        dto.setCreateTime(createTime);
        dto.setOnline(status);
        return dto;
    }

    public ActivityCommonInfoDTO getActivityInfoNoCache(Integer belongType, Long activityId){
        ActivityCommonInfoDTO dto=null;
        if(BelongTypeEnum.PLATFORM.getCode().equals(belongType)){
            PlatformActivityDO platformActivityDO = platformActivityRepository.findById(activityId).orElse(null);
            if(platformActivityDO!=null){
                dto=buildActivityCommonInfoDTO(platformActivityDO.getId(),
                        platformActivityDO.getActivityType(),
                        platformActivityDO.getStartTime(),
                        platformActivityDO.getEndTime(),
                        platformActivityDO.getActivityName(),
                        platformActivityDO.getCreateTime(),
                        PlatformActivityOuterStatusEnum.ONGOING.getCode().equals(platformActivityDO.getOuterStatus())
                );
            }
        }else if(BelongTypeEnum.MERCHANT.getCode().equals(belongType)){
            MerchantActivityDO merchantActivityDO = merchantActivityRepository.findById(activityId).orElse(null);
            if(merchantActivityDO!=null){
                dto=buildActivityCommonInfoDTO(merchantActivityDO.getId(),
                        merchantActivityDO.getActivityType(),
                        merchantActivityDO.getStartTime(),
                        merchantActivityDO.getEndTime(),
                        merchantActivityDO.getActivityName(),
                        merchantActivityDO.getCreateTime(),
                        MerchantActivityInnerStatusEnum.ONGOING.getCode().equals(merchantActivityDO.getInnerStatus())
                );
            }
        }
        return dto;
    }

    //查询活动数据（缓存8小时）
    public ActivityCommonInfoDTO getActivityInfo(Integer belongType, Long activityId){
        String cacheKey=MkRedisKeyConstants.getTempKeyPrefix("act", belongType, activityId);
        String act = redisStringUtils.get(cacheKey, Constants.REDIS_MARKETING_INDEX);
        if(StringUtils.hasLength(act)){
            return JSONUtil.toBean(act,ActivityCommonInfoDTO.class);
        }
        ActivityCommonInfoDTO dto=getActivityInfoNoCache(belongType,activityId);
        if(dto!=null){
            redisStringUtils.set(cacheKey,JSONUtil.toJsonStr(dto),MkRedisKeyConstants.TEMP_EXPIRED,Constants.REDIS_MARKETING_INDEX);
        }
        return dto;
    }
}